package com.xsir.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xsir.dto.ArticleView;
import com.xsir.entity.*;
import com.xsir.mapper.*;
import com.xsir.service.IArticleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xsir
 * @date 2020/9/9
 */
@Transactional(rollbackFor = Exception.class)
@Service
@Slf4j
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements IArticleService {
    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private ArticleCategoryRelMapper articleCategoryRelMapper;
    @Resource
    private ArticleTagRelMapper articleTagRelMapper;
    @Resource
    private CategoryMapper categoryMapper;
    @Resource
    private TagMapper tagMapper;
    
    @Override
    public boolean publish(Long uid, ArticleView articleView) {
        Article article = articleView.getArticle();
        article.setAuthorId(uid);
        article.setStatus(articleView.getPublish() ? 0 : 1);
        Category category = articleView.getCategory();
        List<Tag> tags = articleView.getTags();
        
        // 文章摘要
        // int length = article.getContent().length() > 100 ? 100 : article.getContent().length();
        // article.setSummary(article.getContent().substring(0, length));
        
        if (null == article.getId()) {
            // id == null，添加文章
            article.setUpdateTime(article.getCreateTime());
            articleMapper.insertKey(article);
        } else {
            // id != null，更新
            article.setUpdateTime(LocalDateTime.now());
            // 更新文章
            articleMapper.updateById(article);
        }
        // 添加类别和标签
        addCategory(article, category);
        addTags(article, tags);
        
        return true;
    }
    
    @Override
    public void delete(Integer articleId) {
        // 1. 删除文章
        articleMapper.deleteById(articleId);
        // 2. 删除文章和类别的关系
        articleCategoryRelMapper.delete(new QueryWrapper<ArticleCategoryRel>().eq("article_id", articleId));
        // 3. 删除文章和标签的关系
        articleTagRelMapper.delete(new QueryWrapper<ArticleTagRel>().eq("article_id", articleId));
    }
    
    public IPage<Article> selectByPage(Page<Article> page, QueryWrapper<Article> wrapper) {
        // articleMapper.selectMapsPage(page, wrapper);
        return null;
    }
    
    /**
     * 给文章添加或更新类别
     *
     * @param article  文章
     * @param category 类别
     */
    private void addCategory(Article article, Category category) {
        if (null == category || "".equals(category.getName().trim())) {
            articleCategoryRelMapper.delete(new QueryWrapper<ArticleCategoryRel>().eq("article_id", article.getId()));
            return;
        }
        
        // 若类别不存在，则先创建类别
        if (null == category.getId()) {
            category.setUserId(article.getAuthorId());
            category.setCreateTime(LocalDateTime.now());
            category.setUpdateTime(category.getCreateTime());
            categoryMapper.insertKey(category);
        }
        // 类别存在，则决定给文章添加或更新类别
        ArticleCategoryRel articleCategoryRel = new ArticleCategoryRel();
        articleCategoryRel.setArticleId(article.getId());
        articleCategoryRel.setCategoryId(category.getId());
        articleCategoryRel.setCreateTime(LocalDateTime.now());
        // 更新受影响行为0，则添加
        if (articleCategoryRelMapper.update(articleCategoryRel, new UpdateWrapper<ArticleCategoryRel>().eq("article_id", article.getId())) == 0) {
            articleCategoryRelMapper.insert(articleCategoryRel);
        }
    }
    
    /**
     * 给文章添加或更新标签
     *
     * @param article 文章
     * @param tags    标签列表
     */
    private void addTags(Article article, List<Tag> tags) {
        if (null == tags || tags.isEmpty()) {
            articleTagRelMapper.delete(new QueryWrapper<ArticleTagRel>().eq("article_id", article.getId()));
            return;
        }
        // 新标签
        List<Tag> newTags = tags.stream().filter(tag -> null == tag.getId()).collect(Collectors.toList());
        // 已存在的标签
        tags = tags.stream().filter(tag -> null != tag.getId()).collect(Collectors.toList());
        // 若有新标签，先创建新标签
        if (!newTags.isEmpty()) {
            newTags.forEach(tag -> {
                tag.setUserId(article.getAuthorId());
            });
            // 批量添加并返回主键
            tagMapper.insertBatch(newTags);
            tags.addAll(newTags);
        }
        // 更新文章标签或添加新标签（先删除文章所有标签，再添加）
        articleTagRelMapper.delete(new QueryWrapper<ArticleTagRel>().eq("article_id", article.getId()));
        articleTagRelMapper.insertBatch(article.getId(), tags.stream().map(Tag::getId).collect(Collectors.toList()));
    }
}
